/**
 * CoveredDice.java
 *
 * @author Beatrice Bacelli
 * @author Luca Bedogni
 * @author Silvia Righini
 */
package unibo.lsb.logic;

import java.io.Serializable;

/**
 * Class containing two Dice and a PlayerId, should represent the information
 * passed between turns: the real dice, the declared value, and the identity of
 * the player who passed the dice.
 */
public class CoveredDice implements Serializable {
	/** dice that has been declared */
	Dice declared;
	/** dice that has been passed */
	Dice covered;
	/** player who passed me the dice */
	PlayerId player;

	/**
	 * Constructor with Player
	 * 
	 * @param declared
	 *            the dice which was declared
	 * @param covered
	 *            the real dice which was hidden
	 * @param player
	 *            the player as Player
	 */
	public CoveredDice(Dice declared, Dice covered, PlayerId player) {
		super();
		this.declared = declared;
		this.covered = covered;
		this.player = player;
	}

	/**
	 * Constructor with PlayerId
	 * 
	 * @param declared
	 *            the dice which was declared
	 * @param covered
	 *            the real dice which was hidden
	 * @param player
	 *            the player as PlayerId
	 */
	public CoveredDice(Dice declared, Dice covered, Player player) {
		super();
		this.declared = declared;
		this.covered = covered;
		this.player = player.getPlayerId();
	}

	/**
	 * @return the dice which was declared
	 */
	public Dice getDeclared() {
		return declared;
	}

	/**
	 * @return the real dice which was covered
	 */
	public Dice getCovered() {
		return covered;
	}

	/**
	 * Returns the player who played this dice
	 * 
	 * @return the PlayerId of the player who played this dice
	 */
	public PlayerId getPlayerId() {
		return player;
	}

	/**
	 * Assigns penalty to the player who deserves it when one player doubts
	 * 
	 * @param playerInTurn
	 *            player who's playing now (who accepts)
	 * 
	 * @return a LastAssignedPenalty composed of the PlayerId of the player who
	 *         took the penalty, and the value of the penalty (1 or 2)
	 */
	public LastAssignedPenalty doubt(PlayerId playerInTurn) {
		PlayerId playerWhoGetsPenalty;
		int penalty;
		if (this.getCovered().isEqualOrBigger(this.getDeclared())) {
			playerWhoGetsPenalty = playerInTurn;
			/* Player who doubted gets penalty */
		} else {
			playerWhoGetsPenalty = player;
			/* Player who passed gets penalty */
		}

		if (this.getCovered().is21() || this.getDeclared().is21()) {
			penalty = 2;
		} else {
			penalty = 1;
		}
		return new LastAssignedPenalty(playerWhoGetsPenalty, penalty);
	}

	/**
	 * Assigns penalty when player accepts a 21. This method should be called
	 * only if the declared value is 21 (since only 21 can be accepted).
	 * 
	 * @param playerInTurn
	 *            player who's playing now (who accepts)
	 * 
	 * @return a LastAssignedPenalty composed of the PlayerId of the player who
	 *         took the penalty, and the value of the penalty (1). The PlayerId
	 *         will be the one of the player who accepted the penalty.
	 */
	public LastAssignedPenalty accept(PlayerId playerInTurn) {
		if (!this.getDeclared().is21()) {
			throw new RuntimeException(
					"Only 21 can be accepted. This value is "
							+ this.getDeclared());
		}
		return new LastAssignedPenalty(playerInTurn, 1);
	}
}
